﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Taxonomy;
using MS.InformationManagement.ContentHub.CustomFields;
using MS.InformationManagement.ContentHub.ObjectDef.CustomFields;
using MS.InformationManagement.Core.Support;
using MS.InformationManagement.Core.TransactionsResponse;
using MS.InformationManagement.DAL.DocumentCenter;
using MS.InformationManagement.DAL.RecordCenter;
using MS.InformationManagement.Support;
using MS.InformationManagement.Support.Constants;
using Office = Microsoft.Office.DocumentManagement.DocumentSets;
using Microsoft.SharePoint.Utilities;

namespace MS.InformationManagement.Core.Documentset
{
    public class RadicadoInternoActions : BaseDocumentSet<RadicadoInterno>, IRadicado
    {

        #region Fields

        LinkDocuments.LinkDocuments _docLink;

        #endregion

        #region Constructors

        public RadicadoInternoActions(RadicadoInterno radicado) : base(radicado) { }

        public RadicadoInternoActions() { }

        #endregion

        #region fields

        string newId;

        #endregion

        #region [BaseDocumentSet Members]

        public override string NewRadicado(SPFolder parentFolder)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite currentSite = new SPSite(SPContext.Current.Web.Url))
                {
                    using (SPWeb currentWeb = currentSite.OpenWeb())
                    {
                        this.CurrentWeb = currentWeb;
                        this.CurrentWeb.AllowUnsafeUpdates = true;

                        //Creating document set in target library

                        this.NewRadicado();

                        //Creating radicado in record

                        var newRadicado = RadicadosHelper.GetDocumentSetById(this.CurrentDocumentSet.Item.ID, this.CurrentDocumentSet.Item.ParentList.Title, currentWeb);

                        _docLink = new LinkDocuments.LinkDocuments(parentFolder, newRadicado.Folder);
                        _docLink.AddLinkDocumentToFolder(this.CurrentRadicado.Asunto);
                    }
                }
            });
            return this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_UNIQUE_ID].ToString();
        }

        public override ITransactionResponse NewRadicado()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite currentSite = new SPSite(SPContext.Current.Web.Url))
                {
                    using (SPWeb currentWeb = currentSite.OpenWeb())
                    {
                        Hashtable requiredProperties = new Hashtable();
                        string currentDepartment = PeopleHelper.GetPropertyUserProfile(GlobalConstants.UP_DEPARTMENT, CurrentRadicado.SelectedDestinatario.FirstOrDefault().User.LoginName);
                        int currentUserSection = this.getUserSection(currentDepartment).Id.Value;
                        requiredProperties.Add(CustomSiteColumns.FIELD_DOCSET_DEPARTMNET, currentUserSection);
                        requiredProperties.Add(CustomSiteColumns.FIELD_DOCSET_KIND, TermStoreHelper.GetTaxonomyFieldByTerm(GlobalConstants.METADATA_GROUP_NAME, GlobalConstants.METADATA_TERM_TIPOS, GlobalConstants.METADATA_TERM_TIPO_INTERNO));
                        this.CurrentWeb = currentWeb;
                        this.CurrentWeb.AllowUnsafeUpdates = true;
                        this.CreateDocument(this.CurrentRadicado.SelectedDestinatario.FirstOrDefault().User.LoginName, GlobalConstants.CTTN_RADICADO_INTERNO, this.CurrentRadicado.Name, requiredProperties);
                        this.CurrentDocumentSet.Folder.Item.Update();
                        this.updateMetadata();
                    }
                }
            });

            ITransactionResponse response = new BaseRadicadoOperationResponse();
            response.Result = true;
            response.ResponseMessage = string.Format(GlobalConstants.SUCCESS_RADICADO_CREATION, "interno", newId);
            return response;
        }

        public override void UpdateRadicado()
        {
            this.CurrentDocumentSet = GetDocumentSet(this.CurrentRadicado.Id.Value);
            SPContext.Current.Web.AllowUnsafeUpdates = true;
            this.CurrentDocumentSet.Folder.Item.Update();
            this.LogUpdate();
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_ASUNTO] = this.CurrentRadicado.Asunto;
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_DESCRIPCION] = this.CurrentRadicado.Description;
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_SUBSECCION] = this.CurrentRadicado.IDSubSeccion.HasValue ? int.Parse(this.CurrentRadicado.IDSubSeccion.ToString()) : 0;
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_TRD] = this.CurrentRadicado.IDTRD.HasValue ? int.Parse(this.CurrentRadicado.IDTRD.ToString()) : 0;
            //Setting maxresponsedate
            if (CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCUMENT_MAXRESPONSEDATE] == null && CurrentRadicado.IDTRD.HasValue && CurrentRadicado.IDTRD.Value != 0 && getDaysForResponse() != null)
                CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCUMENT_MAXRESPONSEDATE] = getDaysForResponse();
            this.LogUpdate();
            this.CurrentDocumentSet.Folder.Item.Update();
            //this.RemoveFiles(this.CurrentDocumentSet);
            this.LoadFilesToDocumentSet();
            SPContext.Current.Web.AllowUnsafeUpdates = false;
        }

        public override string GetTargetLibrary(string target)
        {
            return target.Split('\\')[1];
        }

        public override RadicadoInterno GetRadicado(int id)
        {
            RadicadoInterno r = default(RadicadoInterno);

            Guid siteGuid = SPContext.Current.Site.ID;
            SPSecurity.RunWithElevatedPrivileges(delegate() {
                using (SPSite overridenSecuritySite = new SPSite(siteGuid))
                {
                    using (SPWeb overrideSecurityWeb = overridenSecuritySite.OpenWeb())
                    {
                        SPTimeZoneCollection timeZoneColl = SPRegionalSettings.GlobalTimeZones;
                        var tz = timeZoneColl.OfType<SPTimeZone>().Where(x => x.ID == 35).FirstOrDefault();

                        SPDocumentLibrary library = overrideSecurityWeb.Lists.TryGetList(TargetLibrary) as SPDocumentLibrary;
                        if (library == null) { throw new Exception(string.Format("Verifique que la biblioteca de documentos {0} existe.")); }
                        SPListItem listItem = library.GetItemById(id);
                        if (listItem == null) { throw new Exception(string.Format("No existe un documento con id {1} en la biblioteca {0}", TargetLibrary, id)); }
                        if (listItem.ContentType.Name.Equals(GlobalConstants.CTTN_RADICADO_INTERNO))
                        {
                            r = new RadicadoInterno();

                            r.Archivado = listItem[CustomSiteColumns.FIELD_DOCUMENT_FILED] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_FILED]);
                            r.Asunto = listItem[CustomSiteColumns.FIELD_DOCSET_ASUNTO] == null ? string.Empty
                               : listItem[CustomSiteColumns.FIELD_DOCSET_ASUNTO].ToString();
                            r.Cancelado = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_CANCEL] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_CANCEL]);
                            r.Categories = listItem[CustomSiteColumns.FIELD_DOCUMENT_CATEGORY] == null ? null
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_CATEGORY] as TaxonomyFieldValue;
                            r.ChildDocuments = listItem[CustomSiteColumns.FIELD_DOCSET_ATTACHED_DOCUMENTS] as SPFieldMultiColumnValue;
                            r.Countries = listItem[CustomSiteColumns.FIELD_DOCUMENT_COUNTRY] == null ? null
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_COUNTRY] as TaxonomyFieldValue;
                            r.Created = Convert.ToDateTime(listItem[SPBuiltInFieldId.Created]);
                            r.DeliveryLogs = listItem[CustomSiteColumns.FIELD_DOCUMENT_DELIVERY_LOG] == null ? new List<DeliveryTraceabilityEntry>()
                                : (listItem[CustomSiteColumns.FIELD_DOCUMENT_DELIVERY_LOG] as DeliveryTraceabilityFieldValue).Entries;
                            r.DepartamentoUsuario = listItem[CustomSiteColumns.FIELD_DOCSET_DEPARTMNET] == null ? new Nullable<double>()
                                : Convert.ToDouble(listItem[CustomSiteColumns.FIELD_DOCSET_DEPARTMNET]);
                            r.Description = listItem[CustomSiteColumns.FIELD_DOCSET_DESCRIPCION] == null ? string.Empty
                                 : listItem[CustomSiteColumns.FIELD_DOCSET_DESCRIPCION].ToString();
                            r.Destinatario = new List<string>();
                            r.DestinatarioId = new List<Nullable<int>>();
                            if (listItem[CustomSiteColumns.FIELD_DOCSET_DESTINATARIO] != null)
                            {
                                SPFieldUserValueCollection destinatarios = new SPFieldUserValueCollection(listItem.Web, listItem[CustomSiteColumns.FIELD_DOCSET_DESTINATARIO].ToString());
                                r.Destinatario = (from lookup in destinatarios
                                                  select lookup.LookupValue).ToList();
                                r.DestinatarioId = (from lookup in destinatarios
                                                    select new Nullable<int>(lookup.LookupId)).ToList();
                            }
                            r.Devuelto = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_RETURNED] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_RETURNED]);
                            r.Digitalizado = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_CAPTURED] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_CAPTURED]);
                            r.Document_Documental_Type_ID = listItem[CustomSiteColumns.FIELD_DOCUMENT_DCOUMENTAL_TYPE_ID] == null ? new Nullable<Int32>()
                                : Convert.ToInt32(listItem[CustomSiteColumns.FIELD_DOCUMENT_DCOUMENTAL_TYPE_ID]);
                            r.DocumentID = listItem[CustomSiteColumns.FIELD_DOCSET_DOCUMENTID] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCSET_DOCUMENTID].ToString();
                            r.DocumentIDValue = listItem[CustomSiteColumns.FIELD_DOCSET_UNIQUE_ID] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCSET_UNIQUE_ID].ToString();
                            r.Enviado = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_SENT] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_SENT]);
                            r.EnvioRechazo = listItem[CustomSiteColumns.FIELD_DOCUMENT_MOTIVO_RECHAZO] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_MOTIVO_RECHAZO].ToString();
                            r.FechaDeAgendado = listItem[CustomSiteColumns.FIELD_DOCSET_FECHA_AGENDADO] == null ? new Nullable<DateTime>()
                                : Convert.ToDateTime(listItem[CustomSiteColumns.FIELD_DOCSET_FECHA_AGENDADO]);
                            r.FechaRespuesta = listItem[CustomSiteColumns.FIELD_DOCUMENT_MAXRESPONSEDATE] == null ? new Nullable<DateTime>()
                                : Convert.ToDateTime(listItem[CustomSiteColumns.FIELD_DOCUMENT_MAXRESPONSEDATE]);
                            r.Id = listItem.ID;
                            r.IDSubSeccion = listItem[CustomSiteColumns.FIELD_DOCUMENT_SUBSECCION] == null ? new Nullable<double>()
                                : Convert.ToDouble(listItem[CustomSiteColumns.FIELD_DOCUMENT_SUBSECCION]);
                            r.IDTRD = listItem[CustomSiteColumns.FIELD_DOCSET_TRD] == null ? new Nullable<double>()
                                : Convert.ToDouble(listItem[CustomSiteColumns.FIELD_DOCSET_TRD]);
                            r.Impreso = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_PRINTED] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_PRINTED]);
                            r.Incluido = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_FILED] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_FILED]);
                            r.ListId = library.ID;
                            r.LogEntries = listItem[CustomSiteColumns.FIELD_DOCUMENT_TRACEABILITY_LOG] == null ? new List<TraceabilityEntry>()
                                : (listItem[CustomSiteColumns.FIELD_DOCUMENT_TRACEABILITY_LOG] as DocumentTraceabilityFieldValue).Entries;
                            r.NoActa = listItem[CustomSiteColumns.FIELD_DOCUMENT_ACTA_ID] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_ACTA_ID].ToString();
                            r.NoRadicado = listItem[CustomSiteColumns.FIELD_DOCSET_ID_RADICADO] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCSET_ID_RADICADO].ToString();
                            r.NúmeroExpediente = listItem[CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID].ToString();
                            r.NúmeroTomo = listItem[CustomSiteColumns.FIELD_VOLUME_ID] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_VOLUME_ID].ToString();
                            r.ObservacionEnvio = listItem[CustomSiteColumns.FIELD_DOCUMENT_OBSERVACIONES_ENVIO] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_OBSERVACIONES_ENVIO].ToString();
                            r.Observaciones = listItem[CustomSiteColumns.FIELD_DOCUMENT_OBSERVACIONES] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_OBSERVACIONES].ToString();
                            r.ObservacionesAdministrador = listItem[CustomSiteColumns.FIELD_DOCUMENT_OBSERVACIONES_ADMIN] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_OBSERVACIONES_ADMIN].ToString();
                            r.Pesado = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_WEIGHT] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_WEIGHT]);
                            r.Radicador = listItem[CustomSiteColumns.FIELD_DOCUMENT_RADICADOR] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_RADICADOR].ToString();
                            r.Recibido = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_DELIVERED] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_DELIVERED]);
                            r.RecibidoCorrespondencia = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_WINDOW] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS_WINDOW]);
                            r.RecibidoInterno = listItem[CustomSiteColumns.FIELD_DOCSET_INTERNAL_RECEPTION] == null ? new Nullable<bool>()
                                : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCSET_INTERNAL_RECEPTION]);
                            r.RemitenteDestinatario = listItem[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT].ToString();
                            r.Status = listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS] == null ? null
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_STATUS] as TaxonomyFieldValue;
                            r.Tipo = listItem[CustomSiteColumns.FIELD_DOCSET_KIND] == null ? null
                                : listItem[CustomSiteColumns.FIELD_DOCSET_KIND] as TaxonomyFieldValue;
                            r.TipoAnexo = listItem[CustomSiteColumns.FIELD_DOCUMENT_TIPO_DE_ANEXO] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_TIPO_DE_ANEXO].ToString();
                            r.TipoDocumento = listItem[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE].ToString();
                            r.TipoRadicado = r.Tipo.Label;
                            r.Titulo = listItem[CustomSiteColumns.FIELD_DOCSET_DESCRIPCION] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_DOCSET_DESCRIPCION].ToString();
                            r.UsuarioAsignado = listItem[CustomSiteColumns.FIELD_EXPEDIENTE_ASSIGNED] == null ? string.Empty
                                : listItem[CustomSiteColumns.FIELD_EXPEDIENTE_ASSIGNED].ToString();

                            Office.DocumentSet currentDoc = GetDocumentSet(id, overrideSecurityWeb);

                            r.AttachedFiles = (from file in currentDoc.Folder.Files.OfType<SPFile>()
                                               where file.Item.ContentType.Name != GlobalConstants.CTTN_COPIAS_RADICADO
                                               select new FileEntity
                                               {
                                                   CreationDate = tz.UTCToLocalTime(file.TimeCreated.ToUniversalTime()),
                                                   FileContent = file.OpenBinary(),
                                                   FileName = file.Name,
                                                   FileSize = file.OpenBinary().Length / 1024,
                                                   IsMainDocument = ListHelper.ConvertToBoolean(file.Item[CustomSiteColumns.FIELD_DOCUMENT_IS_MAIN] + "")
                                               }).ToList();

                            r.AttachedCopys = (from file in currentDoc.Folder.Files.OfType<SPFile>()
                                               where file.Item.ContentType.Name == GlobalConstants.CTTN_COPIAS_RADICADO
                                               select new DAL.DTOs.ContactsDTO
                                               {
                                                   IdItem = file.Item.ID,
                                                   Id = file.Item[CustomSiteColumns.FLD_COPY_CONTACT_ID] + "",
                                                   Direccion = file.Item[CustomSiteColumns.FLD_COPY_CONTACT_ADDRESS] + "",
                                                   Telefono = file.Item[CustomSiteColumns.FLD_COPY_CONTACT_PHONE] + "",
                                                   Email = file.Item[CustomSiteColumns.FLD_COPY_CONTACT_EMAIL] + "",
                                                   IdMedioEnvio = file.Item[CustomSiteColumns.FLD_COPY_ENVIO_ID] + "",
                                                   MedioEnvio = file.Item[CustomSiteColumns.FLD_COPY_ENVIO_NAME] + "",
                                                   Nombre = file.Item[CustomSiteColumns.FLD_COPY_NAME] + "",
                                                   Representante = file.Item[CustomSiteColumns.FLD_COPY_REPRESENTANTE] + ""
                                               }).ToList();
                        }
                    }
                }
            });
            

            return r;
        }

        #endregion

        #region Private Methods

        private Seccion getUserSection(string sectionName)
        {
            using (var dc = new DataContext(SPContext.Current.Web.Url))
            {
                return (from seccion in dc.Secciones
                        where seccion.Title == sectionName
                        select seccion).FirstOrDefault();
            }
        }

        public override void updateMetadata()
        {
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_ASUNTO] = CurrentRadicado.Asunto;
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_ID_RADICADO] = CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_UNIQUE_ID].ToString();
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_SUBSECCION] = CurrentRadicado.IDSubSeccion.HasValue ? int.Parse(CurrentRadicado.IDSubSeccion.ToString()) : 0;
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_TRD] = CurrentRadicado.IDTRD.HasValue ? int.Parse(CurrentRadicado.IDTRD.ToString()) : 0;
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_DESTINATARIO] = CurrentRadicado.SelectedDestinatario;
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCUMENT_STATUS] = TermStoreHelper.GetTaxonomyFieldByTerm(GlobalConstants.METADATA_GROUP_NAME, GlobalConstants.METADATA_TERM_STATUS, GlobalConstants.METADATA_TERM_STATUS_RADICADO);
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_KIND] = TermStoreHelper.GetTaxonomyFieldByTerm(GlobalConstants.METADATA_GROUP_NAME, GlobalConstants.METADATA_TERM_TIPOS, GlobalConstants.METADATA_TERM_TIPO_INTERNO);
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT] = SPContext.Current.Web.CurrentUser.LoginName;
            this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCUMENT_DCOUMENTAL_TYPE_ID] = CurrentRadicado.Document_Documental_Type_ID;

            //Setting maxresponsedate
            if (CurrentRadicado.IDTRD.HasValue && CurrentRadicado.IDTRD.Value != 0 && getDaysForResponse() != null)
                CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCUMENT_MAXRESPONSEDATE] = getDaysForResponse();
            this.CurrentDocumentSet.Folder.Item.Update();
            this.LoadFilesToDocumentSet();
            newId = this.CurrentDocumentSet.Folder.Item[CustomSiteColumns.FIELD_DOCSET_UNIQUE_ID].ToString();
        }

        #endregion


    }
}
